//SD_class_Solve.cpp---------------数独类中解题方法的定义
//
//	void SD_C::SolveAll(int);			//递归解题方法
//  bool SD_C::SolveOne(int);           //1解
//
//v.1.0------------------------------------------------------------------

#include<iostream>
#include<ctime>

#include"SD_class.h"
#include"SD_ver.h"

using namespace std;

//1.递归尝试解题
//	int a	1	唯余法
//			0	唯一法
void SD_C::SolveAll(int a)
{
	bool change;

	if (a)												//唯余法
    {
		do
		{
			change = false;
			for (int i = 0; i < 9; i++)
				for (int j = 0; j < 9; j++)
				{
					change += FindSole(i, j);
                    Update_q();
					change += FindSoleAble(i, j);
                    Update_q();
					//TO DO加入其他算法
				}
		} while (change);
	}
	else												//唯一法
	{
		do
		{
			change = false;
			for (int i = 0; i < 9; i++)
				for (int j = 0; j < 9; j++)
                {
					change += FindSole(i,j);
                    Update_q();
                    Print_s();
                }

		} while (change);
	}

	int result = Check_s();								//检查解题进度:1未完成,0完成,－1出错
	
	if (result == 1)									//未完成
	{
        SmallXY();              						//找出最少候选数的位置坐标
        short pv = s[x][y];             				//pv暂存该位置
        while (pv != 0)
        {
            short testV = HighestOneBit(pv);			//提取最高位
            pv -= testV;								//删除pv的最高位1
            SD_C SD1 = *this;                           //生成备份对象SD1
            SD1.s[x][y] = testV;            			//在SD1数组上尝试
            SD1.SolveAll(a);                            //进入递归

        };
	}
	
    if (result == 0)                                    //完成
    {
        cout << "Answer" << ++t << endl;
        double TIME_1 = clock();
        Update_q();                                     //刷新并打印q
        Print_q(0);
        cout<<"用时"<<(TIME_1 - TIME_0)/CLOCKS_PER_SEC<<"s!"<<endl<<endl;
        TIME_0 = TIME_1;
        //TO DO加入一条函数将结果输出到文本文件
    }
}


//2.递归尝试得出1解

bool SD_C::SolveOne()
{
    AllFind();

	int result = Check_s();								//检查解题进度:1未完成,0完成,－1出错

	if (result == 0)									//完成
	{
        //cout << "Answer" << ++t << endl;
        //double TIME_1 = clock();
		Update_q();
        //Print_q(1);
        //cout<<"用时"<<(TIME_1 - TIME_0)/CLOCKS_PER_SEC<<"s!"<<endl;
		//TO DO加入将q输出到文本文件的程序
		return true;
	}

	if (result == 1)									//未完成
	{
        SmallXY();                                      //最少候选数的位置坐标
        short pv = s[x][y];
        while (pv != 0)
        {
            short testV = HighestOneBit(pv);			//提取最高位
            pv -= testV;								//删除pv的最高位1
            SD_C SD1 = *this;                           //生成备份对象SD1
            SD1.s[x][y] = testV;            			//在SD1数组上尝试
            if(SD1.SolveOne())
            {
                for(int i = 0; i < 9; i++)              //将q层层输出
                    for(int j = 0; j < 9; j++)
                        q[i][j] = SD1.q[i][j];
                return true;
            }
        }
	}
	return false;
}

